package org.red_cross_service.interceptor;


import org.red_cross_service.common.anno.NoNeedToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.red_cross_service.utils.RedisUtil;

import java.io.IOException;

@Component
public class AppInterceptor implements HandlerInterceptor {

    public static final String TOKEN_NAME = "Authorization";

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        boolean isHandlerMethod = handler instanceof HandlerMethod;
        if (!isHandlerMethod) return true;
        String requestURI = request.getRequestURI();
        if (isStaticResource(requestURI)) return true;
        //不需要登录的注解
        boolean isNoNeedLogin = ((HandlerMethod) handler).getMethodAnnotation(NoNeedToken.class) != null;
        if (isNoNeedLogin) return true;
        //需要做token校验, 消息头的token优先于请求query参数的token
        String xHeaderToken = request.getHeader(TOKEN_NAME);
        String xRequestToken = request.getParameter(TOKEN_NAME);
        String xAccessToken = null != xHeaderToken ? xHeaderToken : xRequestToken;
        if (null == xAccessToken) {
            this.outputResult(response, "token不存在");
            return false;
        }
        // 判断token 是否过期
        Object cacheObject = redisUtil.getCacheObject(xAccessToken);
        if (null == cacheObject) {
            this.outputResult(response, "token已过期请重新登录");
            return false;
        }
        return true;
    }

    /**
     * 错误输出
     *
     * @param response
     * @param msg
     * @throws IOException
     */
    private void outputResult(HttpServletResponse response, String msg) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED);
        response.getWriter().write("{\"code\": 401, \"msg\": \"" + msg + "\"}");
        response.flushBuffer();
    }

    private boolean isStaticResource(String uri) {
        // 匹配静态资源路径或后缀
        return uri.matches("^/static/.*");
    }
}
